package com.distortiongames.level27.generation
{
	
	/**
	 * ...
	 * @author Jefferson Wagner
	 */
	public class Builder
	{
		private var position:Point;
		private var direction:Direction;
		private var done:Boolean;
		private var parameters:Parameters;
		private var generator:Generator;
		private var turnCounter:int;
		
		public function Builder(generator:Generator, initialPosition:Point, initialDirection:Direction, parameters:Parameters)
		{
			this.generator = generator;
			position = initialPosition;
			direction = initialDirection;
			this.parameters = parameters;
			turnCounter = 2;
			done = false;
		}
		
		public function step():void
		{
			if (turnCounter <= 0)
			{
				if (parameters.turnChance.roll())
				{
					var clockwise:Boolean = Generator.random.nextBoolean();
					if (clockwise)
					{
						direction.clockwise();
					}
					else
					{
						direction.counterClockwise();
					}
					turnCounter = 1;
				}
			}
			else
			{
				turnCounter--;
			}
			
			if (parameters.spawnCorridor.roll())
			{
				var element:int = parameters.elementChance.roll();
				var room:Room = new Room(position.copy(), element, generator.rooms.length);
				generator.rooms.push(room);
				generator.getMap().setTile(position, Map.ROOM_START+room.id);
			}
			else
			{
				generator.getMap().setTile(position, Map.CORRIDOR);
			}
			if (parameters.spawnBranch.roll())
			{
				var childParameters:Parameters = parameters.makeChild();
				var newDirection: Direction = direction.copy();
				var clockwiseChild: Boolean = Generator.random.nextBoolean();
				if (clockwiseChild)
					newDirection.clockwise();
				else
					newDirection.counterClockwise();
				if (parameters.forkChance.roll()) {
					if (clockwiseChild)
						direction.counterClockwise();
					else
						direction.clockwise();
				}
				var child:Builder = new Builder(generator, position.copy(), newDirection, childParameters);
				child.move();
				generator.addBuilder(child);
				turnCounter = 3;
			}
			move();
			if (parameters.age.roll())
				done = true;
		}
		
		public function move():void
		{
			var tempPoint:Point = position.copy();
			var movement:Point = direction.toPoint();
			tempPoint.add(movement);
			if (canMoveToLocation(tempPoint) && isLocationClear(tempPoint))
				position = tempPoint;
			else
			{
				done = true;
			}
		}
		
		protected function isLocationClear(point:Point):Boolean
		{
			var result:Boolean = true;
			var tempDirection:Direction = direction.copy();
			var directions:Vector.<Direction> = tempDirection.getLeftAndRight();
			for each (var direction:Direction in directions)
				result = result && (canMoveToLocation(point.added(direction.toPoint())) && generator.getMap().getTile(point.added(direction.toPoint())) == 0);
			return result;
		}
		
		protected function canMoveToLocation(point:Point):Boolean
		{
			return point.x >= 0 && point.x < generator.getMap().width && point.y >= 0 && point.y < generator.getMap().height && generator.getMap().getTile(point) == 0;
		}
		
		public function isDone():Boolean
		{
			return done;
		}
		
		public function setDirection(direction:Direction):void
		{
			this.direction = direction;
		}
		
		public function getPosition():Point
		{
			return position;
		}
	
	}

}